using System;
using System.Collections.Generic;
using System.Text;

namespace Walson.Multimedia
{
    /// <summary>
    /// 虚拟摇杆，可将多个摇杆虚拟为一个摇杆
    /// </summary>
    public class VirtualJoystick : IDisposable
    {
        #region 私有成员
        // 手柄列表
        private List<Joystick> _lJoystickList;
        #endregion

        #region 公共成员

        #region 枚举
        /// <summary>
        /// 错误代码
        /// </summary>
        public enum ErrorCode
        {
            /// <summary>
            /// 没有错误
            /// </summary>
            JOYERR_NOERROR = 0,
            /// <summary>
            /// 参数错误
            /// </summary>
            JOYERR_PARMS = 165,
            /// <summary>
            /// 无法正常工作
            /// </summary>
            JOYERR_NOCANDO = 166,
            /// <summary>
            /// 操纵杆未连接 
            /// </summary>
            JOYERR_UNPLUGGED = 167,
        }
        #endregion

        #region 结构
        /// <summary>
        /// 控制器状态
        /// </summary>
        public struct JoystickState
        {
            /// <summary>
            /// 摇杆 ID 号
            /// </summary>
            public int ID;
            /// <summary>
            /// 摇杆信息
            /// </summary>
            public JoystickAPI.JOYINFOEX JoystickInfo;
            /// <summary>
            /// 按键列表
            /// </summary>
            public List<byte> ButtonList;
            /// <summary>
            /// 错误代码
            /// </summary>
            public ErrorCode Error;

            /// <summary>
            /// 转换为字符串
            /// </summary>
            /// <returns>转换结果</returns>
            public new string ToString()
            {
                StringBuilder strButtonList = new StringBuilder();
                if (ButtonList.Count > 0)
                    foreach (byte b in ButtonList)
                    {
                        strButtonList.Append(b.ToString() + " ");
                    }
                else
                    strButtonList.Append("无");
                return string.Format(
                     "ID:{0}\r\n" +
                     "按下的按键数量:{1}\t\t标志位:{2}\r\n" +
                     "POV:{3}\t\tSize:{4}\r\n" +
                     "Rpos:{5}\t\tUpos:{6}\t\tVpos:{7}\r\n" +
                     "Xpos:{8}\t\tYpos:{9}\t\tZpos:{10}\r\n" +
                     "按键列表：\r\n{11}",
                     ID,
                     JoystickInfo.dwButtonNumber,
                     JoystickInfo.dwFlags,
                     JoystickInfo.dwPOV,
                     JoystickInfo.dwSize,
                     JoystickInfo.dwRpos,
                     JoystickInfo.dwUpos,
                     JoystickInfo.dwVpos,
                     JoystickInfo.dwXpos,
                     JoystickInfo.dwYpos,
                     JoystickInfo.dwZpos,
                     strButtonList.ToString()
                     );
            }
        }

        #endregion


        #region 属性
        /// <summary>
        /// 虚拟控制器中真实控制器的个数
        /// </summary>
        public int Count
        {
            get
            {
                return _lJoystickList.Count;
            }
            private set
            {

            }
        }
        #endregion

        #region 方法
        /// <summary>
        /// 获取摇杆名称列表
        /// </summary>
        /// <returns>获取结果</returns>
        public string[] GetJoystickNames()
        {
            string[] str = new string[_lJoystickList.Count];
            int i = 0;
            foreach (Joystick j in _lJoystickList)
            {
                str[i] = j.Name;
                i++;
            }
            return str;
        }

        /// <summary>
        /// 释放对摇杆的占用
        /// </summary>
        public void ReleaseCapture()
        {
            foreach (Joystick j in _lJoystickList)
            {
                j.ReleaseCapture();
            }
        }
        #endregion

        #endregion

        #region IDisposable 成员
        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            this.ReleaseCapture();
        }

        #endregion

        #region 事件
        /// <summary>
        /// 摇杆状态变化处理方法
        /// </summary>
        /// <param name="joystickState">摇杆状态</param>
        public delegate void JoystickStateChangedHandler(JoystickState joystickState);
        /// <summary>
        /// 摇杆状态发生变化
        /// </summary>
        public event JoystickStateChangedHandler JoystickStateChanged;
        /// <summary>
        /// 触发摇杆状态变化事件
        /// </summary>
        /// <param name="joystickState"></param>
        protected void onJoystickStateChanged(JoystickState joystickState)
        {
            if (JoystickStateChanged != null)
                JoystickStateChanged(joystickState);
        }
        #endregion

        /// <summary>
        /// 虚拟摇杆，可将多个摇杆虚拟为一个摇杆
        /// </summary>
        public VirtualJoystick()
        {
            int i = 0;
            _lJoystickList = new List<Joystick>();
            while (i < 16)
            {
                Joystick joy = new Joystick(i);
                if (joy.Name != null && joy.Name != string.Empty)
                {
                    //joy.JoystickStateChanged += new Joystick.JoystickStateChangedHandler(JoystickState joy_JoystickStateChanged);
                    joy.JoystickStateChanged += new Joystick.JoystickStateChangedHandler(joy_JoystickStateChanged);
                    joy.Capture();
                    _lJoystickList.Add(joy);
                }
                i++;
            }
        }

        void joy_JoystickStateChanged(Joystick.JoystickState joyInfo)
        {
            JoystickState s=new JoystickState();

            if (joyInfo.ErrorCode == (int)ErrorCode.JOYERR_NOERROR)
            {
                s.ID = joyInfo.ID;
                s.Error = ErrorCode.JOYERR_NOERROR;
                s.ButtonList = joyInfo.ButtonList;
                s.JoystickInfo = joyInfo.JoystickInfo;
            }
            else
            {
                s.ID = joyInfo.ID;
                s.Error = (ErrorCode)joyInfo.ErrorCode;
                for (int i = 0; i < _lJoystickList.Count; )
                {
                    if (_lJoystickList[i].Id == s.ID)
                    {
                        _lJoystickList.RemoveAt(i);
                        break;
                    }
                    else
                        i++;
                }
            }
            onJoystickStateChanged(s);
        }



    }
}
